package com.ybliang.plat.common.rpc.protocol.json;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.TimeZone;

/**
 * JSON序列化
 * @author liangyb1
 *
 */
public class JSON {

	private static final ObjectMapper objectMapper = new ObjectMapper();

	static {
		objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		// 忽略未知属性，防止json字符串中存在，java对象中不存在对应属性的情况出现错误
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
		// 注册一个时间序列化及反序列化的处理模块，用于解决jdk8中localDateTime等的序列化问题
		JavaTimeModule javaTimeModule = new JavaTimeModule();
		javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
		javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));

		javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
		javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

		javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
		javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
		objectMapper.registerModule(javaTimeModule);

		objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
		objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
	}

	public static ObjectMapper getMapper(){
		return objectMapper;
	}

	/**
	 * Object对象序列化为String
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public static String toJSONString(Object obj) throws Exception {
		return getMapper().writeValueAsString(obj);
	}

	/**
	 * Object对象序列化为byte[]
	 * @param obj
	 * @return
	 * @throws Exception
	 */
    public static byte[] toJSONBytes(Object obj) throws Exception {
        return getMapper().writeValueAsBytes(obj);
    }



	/**
	 * str反序列化
	 * @param str
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public static <T> T parseObject(String str, Class<T> clazz) throws Exception {
		return getMapper().readValue(str, clazz);
    }

	/**
	 * byte反序列化
	 * @param b
	 * @param clazz
	 * @param <T>
	 * @return
	 * @throws Exception
	 */
	public static <T> T parseObject(byte[] b, Class<T> clazz) throws Exception {
		return getMapper().readValue(b, clazz);
	}

	public static Map<String, Object> bean2Map(Object obj) throws Exception {
    	return getMapper().readValue(toJSONString(obj), new TypeReference<Map<String, Object>>(){});
    }

}
